home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / 3DGPL.ZIP / 3DGPL / CODE / TRANS / TRANS-FL.C next >
Encoding:
C/C++ Source or Header  |  1995-06-22  |  9.7 KB  |  260 lines

  1. /** 3DGPL *************************************************\
  2.  *  ()                                                    *
  3.  *  3-D transformations of coordinates using floats.      *
  4.  *                                                        *
  5.  *  Defines:                                              *
  6.  *   T_init_math             Creating sin/cos tables;     *
  7.  *                                                        *
  8.  *   T_translation           Shifting of coordinates;     *
  9.  *   T_scaling               Scaling coordinates;         *
  10.  *                                                        *
  11.  *   T_set_world_rotation    Viewer's rotation;           *
  12.  *   T_world_rotation        Transforming coordinates;    *
  13.  *   T_set_self_rotation     Object rotation;             *
  14.  *   T_self_rotation         Transforming coordinates;    *
  15.  *                                                        *
  16.  *   T_perspective           Transform to perspective.    *
  17.  *                                                        *
  18.  *  (6/1995) By Sergei Savchenko. (savs@cs.mcgill.ca).    *
  19.  *  Copyright (c) 1995 Sergei Savchenko.                  *
  20.  *  THIS SOURCE CODE CAN'T BE USED FOR COMERCIAL PURPOSES *
  21.  *  WITHOUT AUTHORISATION                                 *
  22. \**********************************************************/
  23.  
  24. #include <math.h>                           /* sin & cos */
  25. #include "../hardware/hardware.h"           /* fast copy routines */
  26. #include "../trans/trans.h"                 /* 3D mathematics */
  27.  
  28. #define T_RADS                  40.7436642  /* pseudo-grads into rads */
  29.  
  30. float T_wx1,T_wx2,T_wx3,T_wy1,T_wy2,T_wy3,T_wz1,T_wz2,T_wz3;
  31. float T_sx1,T_sx2,T_sx3,T_sy1,T_sy2,T_sy3,T_sz1,T_sz2,T_sz3;
  32. float T_sin[256],T_cos[256];                /* precalculated */
  33.  
  34. /**********************************************************\
  35.  *  Initializing tables.                                  *
  36. \**********************************************************/
  37.  
  38. void T_init_math(void)
  39. {
  40.  int i;
  41.  
  42.  for(i=0;i<256;i++)
  43.  {
  44.   T_sin[i]=sin(i/T_RADS);
  45.   T_cos[i]=cos(i/T_RADS);
  46.  }
  47.  
  48. /**********************************************************\
  49.  *  Translation of coordinates.                           *
  50. \**********************************************************/
  51.  
  52. void T_translation(register int *from,register int *to,int length,
  53.            int addx,int addy,int addz
  54.           )
  55. {
  56.  register int i;
  57.  
  58.  for(i=0;i<length;i++)
  59.  {
  60.   (*to++)=(*from++)+addx;
  61.   (*to++)=(*from++)+addy;
  62.   (*to++)=(*from++)+addz;                   /* translation */
  63.  }
  64. }
  65.  
  66. /**********************************************************\
  67.  *  Scaling coordinates. (takes in float parameters).     *
  68. \**********************************************************/
  69.  
  70. void T_scaling(register int *from,register int *to,int length,
  71.            int mulx,int muly,int mulz
  72.           )
  73. {
  74.  register int i;
  75.  
  76.  for(i=0;i<length;i++)
  77.  {
  78.   (*to++)=(int)(*from++)*mulx;
  79.   (*to++)=(int)(*from++)*muly;
  80.   (*to++)=(int)(*from++)*mulz;
  81.  }                                          /* scaling */
  82. }
  83.  
  84. /**********************************************************\
  85.  *  Constructing rotation matrix. (gam-bet-alp), rotation *
  86.  *  then pitch then roll sequence. gam-rotation, bet-pitch*
  87.  *                                 alp-roll.              *
  88.  *                                                        *
  89.  *          Y^    Z           x'=z*sin(gam)+x*cos(gam)    *  
  90.  *           |   /            y'=y                        *
  91.  *           |  / alp         z'=z*cos(gam)-x*sin(gam)    * 
  92.  *          /|<---+                                       *
  93.  *         | |/   |           x"=x'                       *
  94.  *  -------|-+-----------> X  y"=y'*cos(bet)-z'*sin(bet)  *
  95.  *     bet | |   __           z"=y'*sin(bet)+z'*cos(bet)  *
  96.  *         V/|   /| gam                                   *
  97.  *         /----+             x"'=y"*sin(alp)+x"*cos(alp) *
  98.  *        /  |                y"'=y"*cos(alp)-x"*sin(alp) *
  99.  *       /   |                z"'=z"                      *
  100.  *           |                                            *
  101. \**********************************************************/
  102.  
  103. void T_set_world_rotation(int alp,int bet,int gam)
  104. {
  105.  float cosalp,sinalp,cosbet,sinbet,cosgam,singam;
  106.  
  107.  cosalp=T_cos[alp];
  108.  sinalp=T_sin[alp];
  109.  cosbet=T_cos[bet];
  110.  sinbet=T_sin[bet];
  111.  cosgam=T_cos[gam];
  112.  singam=T_sin[gam];                         /* initializing */
  113.  
  114.  T_wx1=singam*sinbet*sinalp + cosgam*cosalp;
  115.  T_wy1=cosbet*sinalp;
  116.  T_wz1=singam*cosalp - cosgam*sinbet*sinalp;
  117.  
  118.  T_wx2=singam*sinbet*cosalp - cosgam*sinalp;
  119.  T_wy2=cosbet*cosalp;
  120.  T_wz2=-cosgam*sinbet*cosalp - singam*sinalp;
  121.  
  122.  T_wx3=-singam*cosbet;
  123.  T_wy3=sinbet;
  124.  T_wz3=cosgam*cosbet;                       /* calculating the matrix */
  125. }
  126.  
  127. /**********************************************************\
  128.  *  Rotating coordinates.                                 *
  129.  *                                        |wx1 wx2 wx3|   *
  130.  *  T'=T[W]  where:  [x' y' z'] = [x y z]*|wy1 wy2 wy3|   *
  131.  *                                        |wz1 wz2 wz3|   *
  132. \**********************************************************/
  133.  
  134. void T_world_rotation(int *from,register int *to,int length)
  135. {
  136.  register int i;
  137.  register int xt,yt,zt;
  138.  
  139.  for(i=0;i<length;i++)
  140.  {
  141.   xt=*from++;
  142.   yt=*from++;
  143.   zt=*from++;
  144.  
  145.   *to++=(int)(T_wx1*xt+T_wy1*yt+T_wz1*zt);
  146.   *to++=(int)(T_wx2*xt+T_wy2*yt+T_wz2*zt);
  147.   *to++=(int)(T_wx3*xt+T_wy3*yt+T_wz3*zt); 
  148.  }
  149. }
  150.  
  151. /**********************************************************\
  152.  *  Constructing rotation matrix. (alp-bet-gam), roll     * 
  153.  *  then pitch then rotation sequence. gam-rotation,      *
  154.  *                                     bet-pitch, alp-roll*
  155.  *                                                        *
  156.  *          Y^    Z           x'=y*sin(alp)+x*cos(alp)    *   
  157.  *           |   /            y'=y*cos(alp)-x*sin(alp)    *
  158.  *           |  / alp         z'=z                        *
  159.  *          /|<---+                                       *
  160.  *         | |/   |           x"=x'                       *
  161.  *  -------|-+-----------> X  y"=y'*cos(bet)-z'*sin(bet)  *
  162.  *     bet | |   __           z"=y'*sin(bet)+z'*cos(bet)  *
  163.  *         V/|   /| gam                                   *
  164.  *         /----+             x"'=z"*sin(gam)+x"*cos(gam) *
  165.  *        /  |                y"'=y"                      *
  166.  *       /   |                z"'=z"*cos(gam)-x"*sin(gam) *
  167.  *           |                                            *
  168. \**********************************************************/
  169.  
  170. void T_set_self_rotation(int alp,int bet,int gam)
  171. {
  172.  float cosalp,sinalp,cosbet,sinbet,cosgam,singam;
  173.  
  174.  cosalp=T_cos[alp];
  175.  sinalp=T_sin[alp];
  176.  cosbet=T_cos[bet];
  177.  sinbet=T_sin[bet];
  178.  cosgam=T_cos[gam];
  179.  singam=T_sin[gam];                         /* initializing */
  180.  
  181.  T_sx1=cosalp*cosgam-sinalp*sinbet*singam;
  182.  T_sy1=sinalp*cosgam+cosalp*sinbet*singam;
  183.  T_sz1=cosbet*singam;
  184.  
  185.  T_sx2=-sinalp*cosbet;
  186.  T_sy2=cosalp*cosbet;
  187.  T_sz2=-sinbet;
  188.  
  189.  T_sx3=-cosalp*singam-sinalp*sinbet*cosgam;
  190.  T_sy3=cosalp*sinbet*cosgam-sinalp*singam;
  191.  T_sz3=cosbet*cosgam;                       /* calculating the matrix */
  192. }
  193.  
  194. /**********************************************************\
  195.  *  Rotating coordinates.                                 *
  196.  *                                        |sx1 sx2 sx3|   *
  197.  *  T'=T[S]  where:  [x' y' z'] = [x y z]*|sy1 sy2 sy3|   *
  198.  *                                        |sz1 sz2 sz3|   *
  199. \**********************************************************/
  200.  
  201. void T_self_rotation(int *from,register int *to,int length)
  202. {
  203.  register int i;
  204.  register int xt,yt,zt;
  205.  
  206.  for(i=0;i<length;i++)
  207.  {
  208.   xt=*from++;
  209.   yt=*from++;
  210.   zt=*from++;
  211.  
  212.   *to++=(int)(T_sx1*xt+T_sy1*yt+T_sz1*zt);
  213.   *to++=(int)(T_sx2*xt+T_sy2*yt+T_sz2*zt);
  214.   *to++=(int)(T_sx3*xt+T_sy3*yt+T_sz3*zt); 
  215.  }
  216. }
  217.  
  218. /**********************************************************\
  219.  *  Transforming to perspective, coordinates passed ase   *
  220.  *                        supposed to be both volume, and *  
  221.  *                *       Z-clipped, otherwise division   *
  222.  *               /|X      by 0 or overflow can occur.     *
  223.  *              / |                                       *
  224.  *             /  |                                       *
  225.  *            *   |                                       *
  226.  *           /|X' |       X'      X                       *
  227.  *          / |   |    ------- = ---                      *
  228.  *         /  |   |     focus     Z                       *
  229.  *        *---+---+                                       *
  230.  *        0   ^   Z    X'= X*focus/Z                      *
  231.  *            |                                           *
  232.  *          focus                                         *
  233.  *                                                        *
  234.  *  ADDITIONAL FUNCTIONS: 1) changing formats:            *
  235.  *  ---------------------                                 *
  236.  *    source:       x, y ,z,a1,...,aN where N==dimension-3*
  237.  *    destanation:  x',y',  a1,...,aN                     *
  238.  *                                                        *
  239.  *  2) performs translation to the screen centre.         *
  240. \**********************************************************/
  241.  
  242. void T_perspective(register int *from,register int *to,
  243.            int dimension,int length
  244.           )
  245. {
  246.  register int i;
  247.  
  248.  dimension-=3;                              /* other then X,Y */
  249.  
  250.  for(i=0;i<length;i++,from+=dimension,to+=dimension) 
  251.  {                                          /* Z is not being changed */
  252.   to[0]=((((long)from[0])<<T_LOG_FOCUS)/from[2])+HW_SCREEN_X_CENTRE;
  253.   to[1]=((((long)from[1])<<T_LOG_FOCUS)/from[2])+HW_SCREEN_Y_CENTRE;
  254.   HW_copy_int(from+=3,to+=2,dimension);
  255.  }
  256. }
  257.  
  258. /**********************************************************/
  259.